# == Audit
# A model for handling audits. Expects a User model to be available.
#
# Provides the following scopes:
#
# * <tt>desc</tt> - Orders by <tt>created_at</tt> DESC and then <tt>id</tt> DESC
# * <tt>recent</tt> - Returns the last 25 audits
# * <tt>changes_on_attributes</tt> - Returns the audits with changes to the given attribute.
#
# If you want to simply provide some notification of an event or a message.
# Assign to the <tt>messsage</tt> attribute instead of the <tt>change_set</tt>
# attribute.
#
# == Schema Information
#
# Table name: audits
#
#  id           :integer         not null, primary key
#  audited_type :string(255)     not null
#  audited_id   :integer         not null
#  user_id      :integer         not null
#  change_set   :text            not null
#  created_at   :datetime        not null
#
class Audit < ActiveRecord::Base
  MESSAGE = "Message"

  belongs_to :audited, :polymorphic => true
  belongs_to :user

  serialize :change_set, Hash

  scope :desc, :order => "audits.created_at DESC, audits.id DESC"
  scope :recent, :order => "audits.created_at DESC", :limit => 25
  scope :changes_on_attribute, lambda { |attr|
    { :conditions => ["audits.change_set LIKE ?", "%#{attr}:%"]}
  }

  # Create an Audit given the <tt>model</tt>, <tt>change_set</tt> and <tt>user</tt>.
  def self.create_changes(model, change_set, user=nil)
    user_id = user && user.id
    self.create!(:audited => model, :user_id => user_id, :change_set => change_set)
  end

  # Returns a message if this audit was a message.
  def message
    self.change_set.has_key?(MESSAGE) && self.change_set[MESSAGE]
  end

  # Sets this audit to be a message with the given message.
  def message=(message)
    self.change_set = {MESSAGE => message}
  end
end
